<template>
    <div ref="canvas">
        123
    </div>
</template>
<script setup>
let canvas = reactive(null)
import * as THREE from 'three';

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { PLYExporter } from 'three/addons/exporters/PLYExporter.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

let scene, camera, renderer, exporter, mesh;

const params = {
    exportASCII: exportASCII,
    exportBinaryBigEndian: exportBinaryBigEndian,
    exportBinaryLittleEndian: exportBinaryLittleEndian
};

onMounted(() => {
    console.log(canvas)
    init();
    animate();
})


function init() {

    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 100);
    camera.position.set(4, 2, 4);

    scene = new THREE.Scene();
    scene.background = new THREE.Color("#91ffce");
    // scene.fog = new THREE.Fog("#a2db3c", 4, 20);

    exporter = new PLYExporter();

    //
    // 半光
    const hemiLight = new THREE.HemisphereLight("#FFF", 3);
    hemiLight.position.set(0, 0, 0);
    scene.add(hemiLight);
    // 平行光
    const directionalLight = new THREE.DirectionalLight("#f23e3e", 3);
    directionalLight.position.set(0, 20, 10);
    directionalLight.castShadow = true;
    directionalLight.shadow.camera.top = 2;
    directionalLight.shadow.camera.bottom = - 2;
    directionalLight.shadow.camera.left = - 2;
    directionalLight.shadow.camera.right = 2;
    scene.add(directionalLight);

    // ground
    const texture = new THREE.TextureLoader();
    const rightTexture = texture.load('/static/dp.jpg');
    const right_material = new THREE.MeshPhongMaterial({
        // color: 0x00fa9a,
        map: rightTexture
    });
    const geometry_pm = new THREE.PlaneGeometry(40, 40); //地皮大小
    const mesh_box = new THREE.Mesh(geometry_pm, right_material);

    // const ground = new THREE.Mesh(geometry_pm, [right_material]);
    mesh_box.rotation.x = - Math.PI / 2;
    // mesh_box.receiveShadow = true;
    mesh_box.position.set(0, 0, 0);
    scene.add(mesh_box);

    // const geometry = new THREE.PlaneGeometry(1, 1);
    // const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
    // const plane = new THREE.Mesh(geometry, material);
    // scene.add(plane);

    // const grid = new THREE.GridHelper(40, 20, 0x000000, 0x000000);
    // grid.material.opacity = 0.2;
    // grid.material.transparent = true;
    // scene.add(grid);

    // export mesh

    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshPhongMaterial({ vertexColors: true });

    // color vertices based on vertex positions
    const colors = geometry.getAttribute('position').array.slice();
    for (let i = 0, l = colors.length; i < l; i++) {

        if (colors[i] > 0) colors[i] = 0.5;
        else colors[i] = 0;

    }

    geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3, false));

    mesh = new THREE.Mesh(geometry, material);
    mesh.castShadow = true;
    mesh.position.y = 0.5;
    scene.add(mesh);

    //

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    canvas.appendChild(renderer.domElement);

    //

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.target.set(0, 0.5, 0);
    controls.update();

    //

    window.addEventListener('resize', onWindowResize);

    const gui = new GUI();

    gui.add(params, 'exportASCII').name('Export PLY (ASCII)');
    gui.add(params, 'exportBinaryBigEndian').name('Export PLY (Binary BE)');
    gui.add(params, 'exportBinaryLittleEndian').name('Export PLY (Binary LE)');
    gui.open();

}

function onWindowResize() {

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);

}

function animate() {

    requestAnimationFrame(animate);
    renderer.render(scene, camera);

}

function exportASCII() {

    exporter.parse(mesh, function (result) {

        saveString(result, 'box.ply');

    });

}

function exportBinaryBigEndian() {

    exporter.parse(mesh, function (result) {

        saveArrayBuffer(result, 'box.ply');

    }, { binary: true });

}

function exportBinaryLittleEndian() {

    exporter.parse(mesh, function (result) {

        saveArrayBuffer(result, 'box.ply');

    }, { binary: true, littleEndian: true });

}

// const link = document.createElement('a');
// link.style.display = 'none';
// canvas.appendChild(link);

function save(blob, filename) {

    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();

}

function saveString(text, filename) {

    save(new Blob([text], { type: 'text/plain' }), filename);

}

function saveArrayBuffer(buffer, filename) {
    save(new Blob([buffer], { type: 'application/octet-stream' }), filename);
}
</script>
<style></style>